package com.seo.service.transaction.impl;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.seo.mapper.transaction.TransactionMapper;
import com.seo.pojo.transaction.TransactionFlow;
import com.seo.pojo.transaction.TransactionFlowItem;
import com.seo.pojo.transaction.TransactionType;
import com.seo.service.transaction.sdk.TransactionItemService;
import com.seo.service.transaction.sdk.TransactionService;
import com.seo.pojo.ReturnBody;
import com.seo.utils.CustomUtil;
import com.seo.utils.DateHeiUtil;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service("transactionService")
public class TransactionServiceImpl implements TransactionService {

	@Autowired
	private TransactionMapper transactionMapper;

	private Map<String, TransactionItemService> transactionItemServices = new HashMap<>();

	@Override
	public ReturnBody saveTransactionFlow(String tradeId, TransactionFlow tf) {
		log.info("[{}]-【保存账单,账单类型[{}]】", tradeId, tf.getType());
		ReturnBody body = ReturnBody.init();
		String typeCode = tf.getType();

		log.info("[{}]-【校验类型[{}]是否存在】", tradeId, typeCode);
		TransactionType transactionType = transactionMapper.getTransactionTypeByCode(typeCode);
		if (transactionType == null) {
			log.error("[{}]-【账单类型[{}]不存在】", tradeId, typeCode);

			return body.error("账单类型不存在");
		}

		int num = transactionMapper.saveTransactionFlow(tf);
		tf.setCode(CustomUtil.orderCode(3, tf.getId(), tf.getUserId()));
		num = transactionMapper.updateTransactionFlowCode(tf);
		if (num == 0) {
			return body.rollback("账单保存失败");
		}

		return body.success();
	}

	@Override
	public TransactionFlow getTransactionFlow(String transactionCode) {
		return transactionMapper.getTransactionFlowByCode(transactionCode);
	}

	@Override
	public ReturnBody saveTransactionFlowItem(String tradeId, TransactionFlow tf, String payMode, BigDecimal amount,
			String itemCode, String state) {
		ReturnBody body = ReturnBody.init();
		TransactionItemService service = get(itemCode);
		if (service == null) {
			log.info("[{}]-账单科目[{}]不存在", tradeId, itemCode);
			return body.error("账单科目不存在");
		}

		return service.saveTransactionFlowItem(tradeId, tf, payMode, amount, itemCode, state);
	}

	@Override
	public ReturnBody updateTransactionFlow(String tradeId, String transactionCode, String payMode, String state) {

		ReturnBody body = ReturnBody.init();
		TransactionFlow tf = null;
		try {
			log.info("[{}]-【处理账单】-【交易流水号[{}]payMode[{}]】-【开始】", tradeId, transactionCode, payMode);
			if (StringUtils.isEmpty(transactionCode)) {
				log.error("[{}]-【处理账单】--【交易流水号为空】", tradeId);
				return body.error("交易流水号不能为空");
			}

			// 判断交易流水状态
			tf = transactionMapper.getTransactionFlowByCode(transactionCode);
			if (tf == null) {
				log.error("[{}]-【处理账单】-【交易流水不存在】", tradeId);
				return body.error("交易流水不存在");
			}

			if (!TransactionFlow.State.no.equals(tf.getState())) {
				log.error("[{}]-【处理账单】-【账单[{}]状态[{}]不正确】", tradeId, transactionCode, tf.getState());
				return body.error("账单状态不正确");
			}
			tf.setFinishTime(DateHeiUtil.getTime());
			tf.setState(state);
			int num = transactionMapper.updateTransactionFlowStateByTf(tf);
			if (num == 0) {
				log.error("[{}]-【处理账单】-【账单[{}]状态跟更新失败】", tradeId, transactionCode);
				return body.rollback("账单更新失败");
			}
			log.info("[{}]-【处理账单】-【消费账单】-【更新账单子项】", tradeId);
			body.run(updateTransactionItem(tradeId, state, tf, payMode));
			if (!body.isSuccess()) {
				return body;
			}
			log.info("[{}]-【处理账单】-【消费账单】-【更新交易流水状态】-【成功】", tradeId);

			body.put("tf", tf);
			return body.success();
		} catch (Exception e) {
			log.info("[{}]-【处理账单】-【异常】-{}", tradeId, e);
			return body.rollback();
		} finally {
			body.result();
			log.info("[{}]-【处理账单】-【结束】", tradeId);
		}
	}

	@Override
	public void put(String key, TransactionItemService service) {
		transactionItemServices.put(key, service);

	}

	@Override
	public TransactionFlow getTransactionFlowById(long id) {
		return transactionMapper.getTransactionFlowById(id);
	}

	private TransactionItemService get(String payMode) {
		return transactionItemServices.get(payMode);
	}

	public ReturnBody updateTransactionItem(String tradeId, String state, TransactionFlow tf, String payMode) {
		ReturnBody body = ReturnBody.init();

		if (TransactionFlow.State.finish.equals(state)) {
			log.info("[{}]-【处理账单】-【更新账单子项目】-【已支付】", tradeId);
		} else {
			log.info("[{}]-【处理账单】-【更新账单子项目】-【取消】", tradeId);
		}
		List<TransactionFlowItem> tifList = transactionMapper.getTransactionFlowItemList(tf.getId());
		if (tifList != null && tifList.size() > 0) {
			for (TransactionFlowItem tfi : tifList) {
				TransactionItemService service = get(tfi.getItemCode());
				if (service == null) {
					log.info("[{}]-账单科目处理[{}]不存在", tradeId, tfi.getItemCode());
					return body.error("账单科目处理不存在");
				}
				body = service.updateTransactionFlowItem(tradeId, state, tfi, payMode);
				if (!body.isSuccess()) {
					return body;
				}
			}
		}
		return body.success();
	}
}
